package metier.modele;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;

import java.io.Serializable;


/**
 * Les Figures
 * @author Quentin, Vincent, Charlie
 *
 */
public abstract class Figure implements Serializable {

	private Utilisateur owner;
	private int id = -1;

	public static int AJOUT = 10;
	public static int EDIT = 11;
	public static int SUPPRESSION = 12;

	private int status = AJOUT;

	private int x1, x2, y1, y2;

	private Color fg;
	private Color bg;

	// Chaque client aura une couleur attribuée suivant son ID
	public static Color[] couleursClients = { Color.BLACK, Color.BLUE,
			Color.CYAN, Color.GREEN, Color.MAGENTA, Color.ORANGE, Color.PINK,
			Color.RED, Color.YELLOW, Color.GRAY };

	private static final long serialVersionUID = 2662528322958503566L;


	// GET
	public int getX1() {
		return x1;
	}

	public int getX2() {
		return x2;
	}

	public int getY1() {
		return y1;
	}

	public int getY2() {
		return y2;
	}

	public Color getFg() {
		return fg;
	}

	public Color getBg() {
		return bg;
	}

	public int getId() {
		return id;
	}

	public Utilisateur getOwner() {
		return owner;
	}

	public int getStatus() {
		return status;
	}

	// SET
	public void setX1(int v) {
		this.x1 = v;
	}

	public void setX2(int v) {
		this.x2 = v;
	}

	public void setY1(int v) {
		this.y1 = v;
	}

	public void setY2(int v) {
		this.y2 = v;
	}

	public void setCouleurs(Color fg, Color bg) {
		this.fg = fg;
		this.bg = bg;
	}

	public void setId(int id) {
		this.id = id;
	}

	public void setStatus(int status) {
		this.status = status;
	}

	public void setOwner(Utilisateur owner) {
		this.owner = owner;
	}


	
	public abstract void setDonnees(int x1, int y1, int x2, int y2);

	public abstract void tracer(Graphics g, boolean couleursVraies,
			boolean edit, Color color);
	
	public abstract void addDeleteRect(Graphics2D g);

	public abstract boolean pointOnFigure(Point p);

	public abstract boolean pointInFigure(Point p);

	public abstract int pointInEditFigure(Point p); // 2: haut gauche, 1: bas
													// droit, 0: en dehors

	/**
	 * Return the distance from a point to a segment
	 * 
	 * @param ps
	 *            ,pe the start/end of the segment
	 * @param p
	 *            the given point
	 * @return the distance from the given point to the segment
	 */
	public static double distanceToSegment(Point ps, Point pe, Point p) {

		if (ps.x == pe.x && ps.y == pe.y)
			return distance(ps, p);

		int sx = pe.x - ps.x;
		int sy = pe.y - ps.y;

		int ux = p.x - ps.x;
		int uy = p.y - ps.y;

		int dp = sx * ux + sy * uy;
		if (dp < 0)
			return distance(ps, p);

		int sn2 = sx * sx + sy * sy;
		if (dp > sn2)
			return distance(pe, p);

		double ah2 = dp * dp / sn2;
		int un2 = ux * ux + uy * uy;
		return Math.sqrt(un2 - ah2);
	}

	/**
	 * return the distance between two points
	 * 
	 * @param p1
	 *            ,p2 the two points
	 * @return dist the distance
	 */
	public static double distance(Point p1, Point p2) {
		int d2 = (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y);
		return Math.sqrt(d2);
	}

}